/*
 *  CEListEditDlg.cpp
 *  LID Library
 *
 *  Created by Alexander Trutchenko on 09/11/11.
 *  Copyright 2011 League of Independent Developers. All rights reserved.
 *
 */

#include "cocos2dx_extentions/controls/CEListEditDlg.h"

#include "cocos2dx_extentions/controls/CEListView.h"
#include "cocos2dx_extentions/labels/CELabelProtocol.h"
#include "cocos2dx_extentions/controls/CEMenuItemSprite.h"
#include "cocos2dx_extentions/controls/CEMenu.h"
#include "cocos2dx_extentions/utility/CECocos2dUtility.h"

#include "lid_lib/src/strings_and_localization/LLStringUtils.h"

using namespace cocos2d;
using namespace lidlib;

namespace cocosext {

#define CE_LIST_EDIT_VIEW_LIST_ITEM_PRESSED_DELAY 0.3f

/////////////////////////////////////////////////////
//
/** CEListEditDlg 
* ListEditDlg control. Returns it's values to registered delegates
*/
/////////////////////////////////////////////////////

bool CEListEditDlg::createAndAttachToCurrentScene(const CEListEditDlgInfo& info, const ccColor4B& color)
{
	CEListEditDlg *pRet = new CEListEditDlg();
    CCAssert(pRet != NULL, NULL);
    if (pRet->init(info, color))
    {
        pRet->autorelease();
		CCDirector::sharedDirector()->getRunningScene()->addChild(pRet, INT_MAX);
        return true;
    }
    else
    {
        CC_SAFE_DELETE(pRet)
        return false;
    }
}


/////////////////////////////////////////////////////
// Constructor, destructor, init

bool CEListEditDlg::init(const CEListEditDlgInfo& info, const ccColor4B& color)
{
	if (!CEModalView::init(color))
		return false;

	CCSize szBk = this->getContentSize();
	szBk.width -= CE_LIST_EDIT_VIEW_SCREEN_MARGIN*2.f;
	szBk.height -= CE_LIST_EDIT_VIEW_SCREEN_MARGIN*2.f;

	// Recursive RGBA bk
	_wnd = CENodeRGBA::node();
	_wnd->setAnchorPoint(ccp(0.f, 1.f));
	_wnd->setPosition(ccp(CE_LIST_EDIT_VIEW_SCREEN_MARGIN, this->getContentSize().height - CE_LIST_EDIT_VIEW_SCREEN_MARGIN));
	_wnd->setContentSize(szBk);
	this->addChild(_wnd, 0);

	// Background
	_bk = info.wnd;
	_bk->setContentSize(szBk);
	_bk->setAnchorPoint(CCPointZero);
	_bk->setPosition(CCPointZero);
	_wnd->addChild(_bk, 0);	
	
	//Title
	_title = info.title;
	_title->setAnchorPoint(ccp(0.f, 0.5f));
	_title->setPosition(ccp(info.titleMarginLeft, _bk->getContentSize().height - info.titleAreaHeight/2.f));
	_bk->addChild(_title, 0);

	float editShiftX = (_bk->getContentSize().width - info.editBk->getContentSize().width - info.closeBtnSprNorm->getContentSize().width)/3.f;
	float editPosY = _bk->getContentSize().height - info.titleAreaHeight - info.editAreaHeight/2.f;

	//Edit bk
	_editBk = info.editBk;
	_editBk->setAnchorPoint(ccp(0.f, 0.5f));
	_editBk->setPosition(ccp(editShiftX, editPosY));
	_bk->addChild(_editBk, 0);

	//Label
	info.label->setAnchorPoint(ccp(0.f, 0.5f));
	info.label->setPosition(ccp(info.labelMarginLeft, info.editBk->getContentSize().height/2.f));
	info.editBk->addChild(info.label, 0);

	_label = dynamic_cast<CELabelProtocol*>(info.label);
	_label->setString(L"");
	
	//Cancel button
	_btnMenu = CEMenu::node(getHigherTouchPriority(CE_MODAL_VIEW_TOUCH_PRIORITY));
    _btnMenu->setAnchorPoint(CCPointZero);
    _btnMenu->setPosition(ccp(0, _bk->getContentSize().height - info.titleAreaHeight - info.editAreaHeight));
	_btnMenu->setContentSize(CCSize(_bk->getContentSize().width, info.editAreaHeight));
    _bk->addChild(_btnMenu, 0);
	_btnMenu->setIsTouchEnabled(false);

	CEMenuItemSprite* btn = CEMenuItemSprite::itemFromNormalSprite(info.closeBtnSprNorm, info.closeBtnSprPressed, NULL, this, menu_selector(CEListEditDlg::onCancel));
	btn->setAnchorPoint(ccp(1.f, 0.5f));
	btn->setPosition(ccp(_bk->getContentSize().width - editShiftX, _btnMenu->getContentSize().height/2.f));
	_btnMenu->addChild(btn, 0);

	//ListBk
	_listBk = info.listBk;
	_listBk->setAnchorPoint(CCPointZero);
	_listBk->setContentSize(CCSize(_bk->getContentSize().width - 2.f*info.listBkMargin, 
								   _bk->getContentSize().height - info.titleAreaHeight - info.editAreaHeight - info.listBkMargin));
	_listBk->setPosition(ccp(info.listBkMargin, info.listBkMargin));
	_bk->addChild(_listBk, 0);

	//List
	_listView = info.list;
	_listView->setTouchPriority(getHigherTouchPriority(CE_MODAL_VIEW_TOUCH_PRIORITY));
	_listView->setAnchorPoint(CCPointZero);
	_listView->setContentSize(CCSize(info.listBk->getContentSize().width - info.listMarginLeft - info.listMargin, info.listBk->getContentSize().height - 2.f*info.listMargin));
	_listView->setPosition(ccp(info.listMarginLeft, info.listMargin));
	info.listBk->addChild(_listView, 0);
	_listView->setIsEnabled(false);

	// Update list
	_listProcessor = info.listProcessor;
	resetListView();
    _isRetinaOnIpad = info.isRetinaOnIpad;
	
	//Fade out
	_wnd->setOpacity(0);
	_wnd->runAction(CCFadeIn::actionWithDuration(CE_MODAL_VIEW_FADE_TIME));
    
    
	//Start input
	attachWithIME();

	//Open
	open();

	return true;
}

void CEListEditDlg::setMarginBottom(float marginBottom)
{
	float halfTitleAreaHalfHeight = _bk->getContentSize().height - _title->getPosition().y;
	float editAreaHalfHeight = _bk->getContentSize().height - _editBk->getPosition().y - 2.f*halfTitleAreaHalfHeight;
	float listBkmargin = _bk->getContentSize().height - _listBk->getContentSize().height - 2.f*halfTitleAreaHalfHeight - 2.f*editAreaHalfHeight;
	float twoListMargin = _listBk->getContentSize().height - _listView->getContentSize().height;

	// Recursive RGBA bk
	_wnd->setContentSize(CCSize(_wnd->getContentSize().width, this->getContentSize().height - CE_LIST_EDIT_VIEW_SCREEN_MARGIN - marginBottom));

	// Background
	_bk->setContentSize(_wnd->getContentSize());
	
	//Title
	_title->setPosition(ccp(_title->getPosition().x, _bk->getContentSize().height - halfTitleAreaHalfHeight));

	float editPosY = _bk->getContentSize().height - 2.f*halfTitleAreaHalfHeight - editAreaHalfHeight;

	//Edit bk
	_editBk->setPosition(ccp(_editBk->getPosition().x, editPosY));
	
	//Cancel button
    _btnMenu->setPosition(ccp(0, _bk->getContentSize().height - 2.f*halfTitleAreaHalfHeight - 2.f*editAreaHalfHeight));

	//ListBk
	_listBk->setContentSize(CCSize(_listBk->getContentSize().width, 
									   _bk->getContentSize().height - 2.f*halfTitleAreaHalfHeight - 2.f*editAreaHalfHeight - listBkmargin));

	//List
	_listView->setContentSize(CCSize(_listView->getContentSize().width, _listBk->getContentSize().height - twoListMargin));
}

/////////////////////////////////////////////////////
// Main interface

////////////////////////////////////////////////////////
// CCIMEDelegate

bool CEListEditDlg::attachWithIME()
{
    bool bRet = CCIMEDelegate::attachWithIME();
    if (bRet)
    {
        // open keyboard
        CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
        if (pGlView)
        {
            pGlView->setIMEKeyboardState(true);
        }
    }
    return bRet;
}

bool CEListEditDlg::detachWithIME()
{
    bool bRet = CCIMEDelegate::detachWithIME();
    if (bRet)
    {
        // close keyboard
        CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
        if (pGlView)
        {
            pGlView->setIMEKeyboardState(false);
        }
    }
    return bRet;
}

void CEListEditDlg::insertText(const char * text, int len)
{
	_utf8text += text;
	std::wstring newStr = _label->getString() + utf8_string_to_utf16_wstring(std::string(text, len));
	_label->setString(newStr.c_str());
	resetListView();
}

void CEListEditDlg::deleteBackward()
{
    int nStrLen = _utf8text.length();
    if (! nStrLen)
    {
        // there is no string
        return;
    }

	// get the delete byte number
    int nDeleteLen = 1;    // default, erase 1 byte
    while(0x80 == (0xC0 & _utf8text.at(nStrLen - nDeleteLen)))
    {
        ++nDeleteLen;
    }

	_utf8text = _utf8text.substr(0, _utf8text.size() - nDeleteLen);
	std::wstring newStr = utf8_string_to_utf16_wstring(_utf8text);
	_label->setString(newStr.c_str());
	resetListView();
}

void CEListEditDlg::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
{
//	CCLog("CEListEditDlg::keyboardWillShow(): w1 %f h1 %f w2 %f h2 %f", info.begin.size.width, info.begin.size.height, info.end.size.width, info.end.size.height);
    
    float margin = info.end.size.height;

	float scaleFactor = CCEGLView::sharedOpenGLView().getScreenScaleFactor();
    if (_isRetinaOnIpad)
        scaleFactor *= 2.f;
	CCSize realScreenSz = CCEGLView::sharedOpenGLView().getRealScreenSizeInPixes();
	float screenMax = realScreenSz.width;
	float  screenMin = realScreenSz.height;
	if ( screenMax < screenMin)
	{
		screenMax = realScreenSz.height;
		screenMin = realScreenSz.width;
	}

//	CCLog("wpMax %f wpMin %f scaleFactor %f", screenMax, screenMin, scaleFactor);

	if (CCDirector::sharedDirector()->getWinSize().width > CCDirector::sharedDirector()->getWinSize().height)
	{
		margin -= (screenMin - CCDirector::sharedDirector()->getWinSize().height*scaleFactor)/2.f;
		margin /= scaleFactor;
	}
	else
	{
		margin -= (screenMax - CCDirector::sharedDirector()->getWinSize().height*scaleFactor)/2.f;
		margin /= scaleFactor;
	}
			
//    CCLog("---------- margin %f", margin);
    setMarginBottom(margin);
}
void CEListEditDlg::keyboardDidShow(CCIMEKeyboardNotificationInfo& info)
{
//	CCLog("CEListEditDlg::keyboardWillShow(): w1 %f h1 %f w2 %f h2 %f", info.begin.size.width, info.begin.size.height, info.end.size.width, info.end.size.height);
}
void CEListEditDlg::keyboardWillHide(CCIMEKeyboardNotificationInfo& info)
{
//	CCLog("CEListEditDlg::keyboardWillShow(): w1 %f h1 %f w2 %f h2 %f", info.begin.size.width, info.begin.size.height, info.end.size.width, info.end.size.height);
}
void CEListEditDlg::keyboardDidHide(CCIMEKeyboardNotificationInfo& info)
{
//	CCLog("CEListEditDlg::keyboardWillShow(): w1 %f h1 %f w2 %f h2 %f", info.begin.size.width, info.begin.size.height, info.end.size.width, info.end.size.height);
}

/////////////////////////////////////////////////////
// Protected interface
void CEListEditDlg::close()
{
	CEModalView::close();
	_listView->setIsEnabled(false);
	_btnMenu->setIsTouchEnabled(false);
	detachWithIME();
	_wnd->runAction(CCFadeOut::actionWithDuration(CE_MODAL_VIEW_FADE_TIME));
}

void CEListEditDlg::finishClose()
{
	CEModalView::finishClose();
	this->removeFromParentAndCleanup(true);
}

/////////////////////////////////////////////////////
// Private interface

void CEListEditDlg::resetListView()
{
	_listView->removeAllListItems();
	_listProcessor->fillListViewWithMask(_label->getString(), _listView, this, menu_selector(CEListEditDlg::onListItemPressed));
	_listView->setRelativeListPosition(0.f);
}

void CEListEditDlg::onListItemPressed(cocos2d::CCObject* caller)
{
	_label->setString(_listProcessor->getTextOnListItemPressed(caller));
	schedule(schedule_selector(CEListEditDlg::closeWithDelay), CE_LIST_EDIT_VIEW_LIST_ITEM_PRESSED_DELAY);
}

void CEListEditDlg::closeWithDelay(cocos2d::ccTime time)
{
	unschedule(schedule_selector(CEListEditDlg::closeWithDelay));
	close();
}

void CEListEditDlg::onCancel(cocos2d::CCObject* caller)
{
	close();
}

void CEListEditDlg::finishOpen()
{
	CEModalView::finishOpen();

	_listView->setIsEnabled(true);
	_btnMenu->setIsTouchEnabled(true);
}

}; // end namespace cocosext

